﻿using System;
using System.Collections.Generic;
using System.Text;

namespace CompilerPhase4
{
    public class Quad                  //Class to hold values needed for a quad
    {
        int opcode;                                                    //Opcode
        Symbol op1;                                                 //operand 1
        Symbol op2;                                                 //operand 2
        Symbol op3;                                                 //operand 3

        public Quad(int opc, Symbol o1, Symbol o2, Symbol o3)     //Constructor
        {
            opcode = opc;                                    //Intialize opcode
            op1 = o1;                                          //Initialize op1
            op2 = o2;                                          //Initialize op2
            op3 = o3;                                          //Initialize op3
        }

        #region GET/SET METHODS
        public int Opcode         //Opcode geter/setter. Returns or sets opcode
        {
            get
            {
                return opcode;
            }
            set
            {
                opcode = value;
            }
        }
        public int Op1                 //op1 geter/setter. Returns or sets op1
        {
            get
            {
                return op1.Value;
            }
            set
            {
                op1.Value = value;
            }
        }
        public int Op2                //op2 geter/setter. Returns or sets op2
        {
            get
            {
                return op2.Value;
            }
            set
            {
                op2.Value = value;
            }
        }
        public int Op3                //op3 geter/setter. Returns or sets op3
        {
            get
            {
                return op3.Value;
            }
            set
            {
                op3.Value = value;
            }
        }
        public Symbol GetOp1()
        {
            return op1;
        }
        public Symbol GetOp2()
        {
            return op2;
        }
        public Symbol GetOp3()
        {
            return op3;
        }
        #endregion
    }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
    public class QuadTable
    {
        #region FIELDS
        Quad[] quadTable;       //Array of opcodes to function as the quadTable
        int currOpenIndex;                    //First empty index in quad table
        ReserveTable reserveTable;         //Reserve Table to look up mnemonics
        #endregion

        public QuadTable(int tableSize)                           //Constructor
        {
            Initialize(tableSize);                  //Intialize a new QuadTable
        }
/*-----------------------------------------------------------------------------
         * Initialize: Creates a new array of type Op. Sets the counter for   |
         * tracking the open slot in the array to 0.                          |
 *---------------------------------------------------------------------------*/ 
        public void Initialize(int tableSize)
        {
            currOpenIndex = 0;             //set currOpenIndex to head of array
            quadTable = new Quad[tableSize];                //Create quad table
            reserveTable = new ReserveTable();         //Intialize reserveTable
        }
/*-----------------------------------------------------------------------------
         * NextQuad: Returns the value of currOpenIndex to point at the next  |
         * empty location in quadTable.                                       |
 * --------------------------------------------------------------------------*/
        public int NextQuad()
        {
            return currOpenIndex;
        }
/*-----------------------------------------------------------------------------
         * AddQuad: Creates a new Op object in the Quad Table, using values   |
         * provided. Then, increments currOpenIndex to the next open index in |
         * the Quad Table.                                                    |
 * --------------------------------------------------------------------------*/
        public void AddQuad(int opcode, Symbol op1, Symbol op2, Symbol op3)
        {
            Quad temp = new Quad(opcode, op1, op2, op3);//Temporary Quad object
            quadTable[currOpenIndex] = temp; //Store new Quad in the quad table
            currOpenIndex++;  //increment currOpenIndex to new first open index
        }
/*-----------------------------------------------------------------------------
         * GetQuad: Returns the Op object stored in the given index of the    |
         * Quad Table.                                                        |
 *---------------------------------------------------------------------------*/
        public Quad GetQuad(int index)
        {
            return quadTable[index];  //return Op from given index in quadTable
        }
/*-----------------------------------------------------------------------------
         * SetQuad: Changes the values of the Op object held in index to those|
         * provided. Used for backfilling jump addresses later during coding  |
         * generation.                                                        |
 *---------------------------------------------------------------------------*/
        public void SetQuad(int index, int opcode, int op1, int op2, int op3)
        {
            quadTable[index].Opcode = opcode;      //Sets opcode to given value
            quadTable[index].Op1 = op1;               //Sets op1 to given value
            quadTable[index].Op2 = op2;               //Sets op2 to given value
            quadTable[index].Op3 = op3;               //Sets op3 to given value
        }
/*-----------------------------------------------------------------------------
         * GetMnemonic: Returns the string name associated with the given     |
         * opcode.                                                            |
 *---------------------------------------------------------------------------*/
        public string GetMnemonic (int opcode)
        {
            string returnString;                  //String to hold return value
            returnString = reserveTable.LookupCode(opcode);      //Get the name
            return returnString;                   //Return given opcode's name
        }
/*-----------------------------------------------------------------------------
         * PrintReserve: Calls the reserve table's display function to print  |
         * reserve table to console.                                          |
 *---------------------------------------------------------------------------*/
        public void PrintReserve()
        {
            reserveTable.Display();
        }
/*---------------------------------------------------------------------------*/
    }
}
